package com.fr.data.core.db;

import com.fr.base.FRContext;
import com.fr.base.core.DateUtils;
import com.fr.base.core.list.IntList;
import com.fr.base.dav.Env;
import com.fr.base.file.DatasourceManager;
import com.fr.data.core.DataUtils;
import com.fr.data.core.db.dialect.Dialect;
import com.fr.data.core.db.dialect.DialectFactory;
import com.fr.data.core.db.dialect.OracleDialect;
import com.fr.data.core.db.dml.Table;
import com.fr.data.core.db.handler.SQLTypeHandler;
import com.fr.data.core.db.handler.SQLTypeHandlerFactory;
import com.fr.data.impl.DatabaseConnection;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.impl.JNDIDatabaseConnection;
import com.fr.report.script.Primitive;
import java.io.PrintStream;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.jdbc.OracleCallableStatement;

public class DBUtils
{
  public static void applyColumnTypeValue(Dialect paramDialect, Connection paramConnection, Table paramTable, String paramString, PreparedStatement paramPreparedStatement, int paramInt1, int paramInt2, Object paramObject)
    throws SQLException
  {
    FRContext.getLogger().log(Level.INFO, "columnIndex:" + paramInt1 + "[" + paramInt2 + "]" + "<--->" + "columnValue:" + paramObject + "[" + ((paramObject == null) ? "NULL" : paramObject.getClass().getName()) + "]");
    if (isNULL(paramObject))
    {
      paramPreparedStatement.setNull(paramInt1, paramInt2);
      return;
    }
    if (paramDialect.isYearData(paramConnection, paramInt2, paramTable, paramString))
      paramObject = DateUtils.date2Year(paramObject);
    SQLTypeHandlerFactory localSQLTypeHandlerFactory = SQLTypeHandlerFactory.buildSQLTypeHanderFactory();
    SQLTypeHandler localSQLTypeHandler = localSQLTypeHandlerFactory.getTypeHandler(new Integer(paramInt2));
    localSQLTypeHandler.setValue(paramPreparedStatement, paramInt1, paramObject, paramInt2, paramDialect);
  }

  public static boolean isNULL(Object paramObject)
  {
    return ((paramObject == null) || (Primitive.NULL.equals(paramObject)));
  }

  public static int getColumnFRType(int paramInt)
  {
    for (int i = 0; i < DBConstants.STRING_ARRAY.length; ++i)
      if (DBConstants.STRING_ARRAY[i] == paramInt)
        return DBConstants.FR_STRING;
    for (i = 0; i < DBConstants.NUMBER_ARRAY.length; ++i)
      if (DBConstants.NUMBER_ARRAY[i] == paramInt)
        return DBConstants.FR_NUMBER;
    for (i = 0; i < DBConstants.NULL_ARRAY.length; ++i)
      if (DBConstants.NULL_ARRAY[i] == paramInt)
        return DBConstants.FR_NULL;
    for (i = 0; i < DBConstants.STREAM_ARRAY.length; ++i)
      if (DBConstants.STREAM_ARRAY[i] == paramInt)
        return DBConstants.FR_STREAM;
    for (i = 0; i < DBConstants.BOOLEAN_ARRAY.length; ++i)
      if (DBConstants.BOOLEAN_ARRAY[i] == paramInt)
        return DBConstants.FR_BOOLEAN;
    return DBConstants.FR_NULL;
  }

  public static void closeConnection(Connection paramConnection)
  {
    try
    {
      if (paramConnection != null)
      {
        paramConnection.close();
        paramConnection = null;
      }
    }
    catch (SQLException localSQLException)
    {
      FRContext.getLogger().log(Level.WARNING, localSQLException.getMessage(), localSQLException);
    }
  }

  public static void closeStatement(Statement paramStatement)
  {
    try
    {
      if (paramStatement != null)
      {
        paramStatement.close();
        paramStatement = null;
      }
    }
    catch (SQLException localSQLException)
    {
      FRContext.getLogger().log(Level.WARNING, localSQLException.getMessage(), localSQLException);
    }
  }

  public static void closeResultSet(ResultSet paramResultSet)
  {
    try
    {
      if (paramResultSet != null)
      {
        paramResultSet.close();
        paramResultSet = null;
      }
    }
    catch (SQLException localSQLException)
    {
      FRContext.getLogger().log(Level.WARNING, localSQLException.getMessage(), localSQLException);
    }
  }

  public static void rollback(Connection paramConnection)
  {
    if (paramConnection == null)
      return;
    try
    {
      if (!(paramConnection.getAutoCommit()))
      {
        paramConnection.rollback();
        FRContext.getLogger().log(Level.INFO, "Rollback Successfully");
      }
      else
      {
        FRContext.getLogger().log(Level.INFO, "Failed to rollback because of the connection is autoCommit");
      }
    }
    catch (SQLException localSQLException)
    {
      FRContext.getLogger().log(Level.WARNING, localSQLException.getMessage(), localSQLException);
    }
  }

  public static void main(String[] paramArrayOfString)
  {
    String str1 = "oracle.jdbc.driver.OracleDriver";
    String str2 = "jdbc:oracle:thin:@192.168.100.169:1521:orcl10g";
    Object localObject1 = null;
    ResultSet localResultSet = null;
    Connection localConnection = null;
    try
    {
      Class.forName(str1);
      localConnection = DriverManager.getConnection(str2, "scott", "tiger");
      CallableStatement localCallableStatement = null;
      localCallableStatement = localConnection.prepareCall("{call SCOTT.GETENAMEANDJOBS(?,?)}");
      localCallableStatement.registerOutParameter(1, -10);
      localCallableStatement.registerOutParameter(2, -10);
      localCallableStatement.execute();
      localResultSet = (ResultSet)localCallableStatement.getObject(1);
      while (localResultSet.next())
        System.out.println("<tr><td>" + localResultSet.getString(1) + "</td><td>" + localResultSet.getString(2) + "</td></tr>");
    }
    catch (SQLException localSQLException1)
    {
      localSQLException1.printStackTrace();
    }
    catch (Exception localException)
    {
      localException.printStackTrace();
    }
    finally
    {
      try
      {
        if (localResultSet != null)
        {
          localResultSet.close();
          if (localObject1 != null)
            localObject1.close();
          if (localConnection != null)
            localConnection.close();
        }
      }
      catch (SQLException localSQLException2)
      {
      }
    }
  }

  public static Object[] remoteProcedureCall(Connection paramConnection, String paramString, int paramInt)
    throws SQLException
  {
    CallableStatement localCallableStatement;
    paramInt = Math.max(0, paramInt - 1);
    Object[] arrayOfObject = new Object[2];
    Object localObject1 = null;
    ResultSet localResultSet = null;
    Dialect localDialect = DialectFactory.generateDialect(paramConnection);
    if (localDialect instanceof OracleDialect)
    {
      localCallableStatement = null;
      IntList localIntList = new IntList();
      int i = paramString.split("\\?").length - 1;
      if (i > 0)
      {
        localObject1 = paramConnection.prepareCall(paramString);
        localCallableStatement = (CallableStatement)localObject1;
        int j = 1;
        while (true)
        {
          if (j > i)
            break label427;
          localCallableStatement.registerOutParameter(j, -10);
          localIntList.add(j);
          ++j;
        }
      }
      if (paramString.indexOf("$[") != -1)
      {
        HashMap localHashMap = new HashMap();
        int l = 1;
        int i1 = 0;
        StringBuffer localStringBuffer = new StringBuffer();
        while (true)
        {
          int i3;
          String str2;
          while (true)
          {
            int i2 = i1;
            i1 = paramString.indexOf("$[", i2);
            if (i1 < 0)
            {
              localStringBuffer.append(paramString.substring(i2));
              break label341:
            }
            localStringBuffer.append(paramString.substring(i2, i1));
            i3 = paramString.indexOf("]$", i1 + 2);
            if (i3 <= i1)
              break label341:
            str2 = paramString.substring(i1 + 2, i3);
            if ((str2 != null) && (str2.length() > 0))
              break;
            i1 = i3 + 2;
          }
          if (str2.startsWith("@"))
          {
            localIntList.add(l);
            str2 = str2.substring(1);
          }
          int i4 = DataUtils.calculateOracleType(str2);
          if (i4 == -10)
            localIntList.add(l);
          localHashMap.put(new Integer(l), new Integer(i4));
          i1 = i3 + 2;
          localStringBuffer.append("?");
          ++l;
        }
        label341: localObject1 = paramConnection.prepareCall(localStringBuffer.toString());
        localCallableStatement = (CallableStatement)localObject1;
        Iterator localIterator = localHashMap.keySet().iterator();
        while (localIterator.hasNext())
        {
          Integer localInteger = (Integer)localIterator.next();
          localCallableStatement.registerOutParameter(localInteger.intValue(), ((Integer)localHashMap.get(localInteger)).intValue());
        }
      }
      label427: localCallableStatement.execute();
      int k = 1;
      if (localIntList.size() > paramInt)
        k = localIntList.get(paramInt);
      if (localCallableStatement instanceof OracleCallableStatement)
      {
        localResultSet = ((OracleCallableStatement)localCallableStatement).getCursor(k);
      }
      else
      {
        Object localObject2 = localCallableStatement.getObject(k);
        if (localObject2 instanceof ResultSet)
        {
          localResultSet = (ResultSet)localObject2;
        }
        else
        {
          String str1 = localObject2.toString();
          localObject1 = paramConnection.createStatement();
          localResultSet = ((Statement)localObject1).executeQuery(str1);
        }
      }
    }
    else
    {
      localObject1 = paramConnection.prepareCall(paramString, 1003, 1007);
      localCallableStatement = (CallableStatement)localObject1;
      localResultSet = localCallableStatement.executeQuery();
      --paramInt;
      while ((localCallableStatement.getMoreResults()) && (paramInt >= 0))
        localResultSet = localCallableStatement.getResultSet();
    }
    arrayOfObject[0] = localObject1;
    arrayOfObject[1] = localResultSet;
    return ((Object)arrayOfObject);
  }

  public static String[] checkInColumnNames(Connection paramConnection, String paramString, int paramInt)
  {
    ColumnInformation[] arrayOfColumnInformation;
    try
    {
      arrayOfColumnInformation = checkInColumnInformation(paramConnection, paramString, paramInt);
      String[] arrayOfString = new String[arrayOfColumnInformation.length];
      for (int i = 0; i < arrayOfColumnInformation.length; ++i)
        arrayOfString[i] = arrayOfColumnInformation[i].getColumnName();
      return arrayOfString;
    }
    catch (SQLException localSQLException)
    {
      FRContext.getLogger().log(Level.WARNING, localSQLException.getMessage(), localSQLException);
    }
    return new String[0];
  }

  public static ColumnInformation[] checkInColumnInformation(Connection paramConnection, String paramString, int paramInt)
    throws SQLException
  {
    if (paramConnection == null)
      throw new SQLException("Cannot connect to database!");
    Statement localStatement = null;
    ResultSet localResultSet = null;
    try
    {
      if (isProcedure(paramString))
      {
        Object[] arrayOfObject = remoteProcedureCall(paramConnection, paramString, paramInt);
        localStatement = (Statement)arrayOfObject[0];
        localResultSet = (ResultSet)arrayOfObject[1];
      }
      else
      {
        localStatement = paramConnection.createStatement();
        try
        {
          localResultSet = localStatement.executeQuery("select * from (" + paramString + ") t where 4 = 5");
        }
        catch (Exception localException)
        {
          localStatement.close();
          localStatement = paramConnection.createStatement();
          localResultSet = localStatement.executeQuery(paramString);
        }
      }
    }
    catch (SQLException localSQLException)
    {
      if (localResultSet != null)
        localResultSet.close();
      if (localStatement != null)
        localStatement.close();
      throw localSQLException;
    }
    ColumnInformation[] arrayOfColumnInformation = checkInColumnInformationByMetaData(localResultSet.getMetaData());
    localResultSet.close();
    localStatement.close();
    return arrayOfColumnInformation;
  }

  public static ColumnInformation[] checkInColumnInformationByMetaData(ResultSetMetaData paramResultSetMetaData)
    throws SQLException
  {
    int i = paramResultSetMetaData.getColumnCount();
    ColumnInformation[] arrayOfColumnInformation = new ColumnInformation[i];
    for (int j = 0; j < i; ++j)
    {
      arrayOfColumnInformation[j] = new ColumnInformation(paramResultSetMetaData.getColumnLabel(j + 1), paramResultSetMetaData.getColumnType(j + 1), paramResultSetMetaData.getColumnTypeName(j + 1));
      paramResultSetMetaData.getScale(j + 1);
    }
    return arrayOfColumnInformation;
  }

  public static boolean isProcedure(String paramString)
  {
    if (paramString == null)
      return false;
    return ((paramString.trim().startsWith("{")) && (paramString.trim().substring(1).trim().toUpperCase().startsWith("CALL")));
  }

  public static boolean isExsitedTable(DatabaseConnection paramDatabaseConnection, String paramString)
  {
    TableProcedure[] arrayOfTableProcedure;
    try
    {
      arrayOfTableProcedure = FRContext.getCurrentEnv().getSQLTablesProcedure(paramDatabaseConnection, null);
      int i = 0;
      int j = arrayOfTableProcedure.length;
      while (i < j)
      {
        TableProcedure localTableProcedure = arrayOfTableProcedure[i];
        if (paramString.equalsIgnoreCase(localTableProcedure.getName()))
          return true;
        ++i;
      }
    }
    catch (Exception localException)
    {
      localException.printStackTrace();
      FRContext.getLogger().info(localException.getMessage());
    }
    return false;
  }

  public static void refreshDatabase()
  {
    DatasourceManager localDatasourceManager = FRContext.getDatasourceManager();
    Iterator localIterator = localDatasourceManager.getConnectionNameIterator();
    while (true)
    {
      String str1;
      com.fr.data.impl.Connection localConnection;
      do
        while (true)
        {
          do
          {
            if (!(localIterator.hasNext()))
              return;
            str1 = (String)localIterator.next();
            localConnection = localDatasourceManager.getConnection(str1);
          }
          while (!(localConnection instanceof DatabaseConnection));
          DatabaseConnection localDatabaseConnection = (DatabaseConnection)localConnection;
          if (!(localDatabaseConnection instanceof JDBCDatabaseConnection))
            break;
          localObject1 = new JDBCDatabaseConnection();
          localObject2 = ((JDBCDatabaseConnection)localConnection).getDriver();
          str2 = ((JDBCDatabaseConnection)localConnection).getURL();
          str3 = ((JDBCDatabaseConnection)localConnection).getUser();
          str4 = ((JDBCDatabaseConnection)localConnection).getPassword();
          ((JDBCDatabaseConnection)localObject1).setDriver((String)localObject2);
          ((JDBCDatabaseConnection)localObject1).setURL(str2);
          ((JDBCDatabaseConnection)localObject1).setUser(str3);
          ((JDBCDatabaseConnection)localObject1).setPassword(str4);
          localDatasourceManager.putConnection(str1, (com.fr.data.impl.Connection)localObject1);
        }
      while (!(localConnection instanceof JNDIDatabaseConnection));
      Object localObject1 = new JNDIDatabaseConnection();
      Object localObject2 = ((JNDIDatabaseConnection)localConnection).getContextHashtable();
      String str2 = ((JNDIDatabaseConnection)localConnection).getJNDIName();
      String str3 = ((JNDIDatabaseConnection)localConnection).getNewCharsetName();
      String str4 = ((JNDIDatabaseConnection)localConnection).getOriginalCharsetName();
      ((JNDIDatabaseConnection)localObject1).setContextHashtable((Hashtable)localObject2);
      ((JNDIDatabaseConnection)localObject1).setJNDIName(str2);
      ((JNDIDatabaseConnection)localObject1).setNewCharsetName(str3);
      ((JNDIDatabaseConnection)localObject1).setOriginalCharsetName(str4);
      localDatasourceManager.putConnection(str1, (com.fr.data.impl.Connection)localObject1);
    }
  }
}